<?php

namespace App\Kuafu\Order\Model;

use App\Kuafu\Base\Model\BaseModel;
use App\Kuafu\Base\Model\Traits\KfSoftDeletes;
use App\Kuafu\Base\Model\Traits\KfUid;
use App\Kuafu\Coupon\Model\CouponModel;
use App\Kuafu\Customer\Model\CustomerActionLogModel;
use App\Kuafu\Customer\Service\CustomerActionLogService;
use App\Kuafu\CustomerCoupon\Enum\CodeEnum;
use App\Kuafu\CustomerCoupon\Enum\CustomerCouponCacheEnum;
use App\Kuafu\CustomerCoupon\Model\CustomerCouponModel;
use App\Kuafu\Order\Service\OrderDb;
use App\Kuafu\Order\Service\OrderService;
use App\Kuafu\Order\Service\OrderTable;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Relations\Relation;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;

class OrderCouponSplitModel extends BaseModel
{
    use KfUid, KfSoftDeletes;

//    protected $connection = 'mysqlOrder';

    public $timestamps = false;


    // 待使用
    public const STATUS_WAIT = 0;
    // 已使用
    public const STATUS_USED = 1;
    // 已撤销
    public const STATUS_REVOCATION = 2;

    // 默认
    public const COUPON_SOURCE_DEFAULT = 0;
    // 用户小程序的
    public const COUPON_SOURCE_APPLET = 1;
    // POS
    public const COUPON_SOURCE_POS = 2;
    // 券包
    public const COUPON_SOURCE_COUPON_PACKAGE = 3;

    public static string $tableName;
    public static string $connectionName;

    /**
     * @param $shopId
     * @return static
     */
    public static function suffix($shopId)
    {
        if (is_int($shopId) && $shopId < 0) {
            $shopId = 0;
        }

        self::$tableName      = OrderTable::orderCouponTableName($shopId);
        self::$connectionName = OrderDb::orderDbConnection($shopId);

        return new static;
    }

    public function getTable()
    {
        return self::$tableName ?? parent::getTable();
    }

    public function getConnectionName()
    {
        return self::$connectionName ?? parent::getConnectionName();
    }

    public function customerCouponRel(): HasOne
    {
        return $this->hasOne(CustomerCouponModel::class, 'id', 'customerCouponId');
    }


    public static function updateOrderCoupon($orderId, $data, array $excludeId = [])
    {
        // 删除原有优惠券
        self::query()
            ->where('orderId', (int)$orderId)
            ->whereNotIn('id', $excludeId)
            ->update(['isDeleted' => 1]);

        // 写入最新优惠券
        self::query()->insert($data);
    }


    public static function insertOrderCoupon($data)
    {
        self::query()->insert($data);
    }

    /**
     * 根据优惠券 id 获取优惠券信息
     *
     * @param array $ids
     */
    public static function getOrderCouponsById(array $ids = [])
    {
        return self::query()->whereIn('id', $ids)->get();
    }

    /**
     * 核销 订单的所有优惠券
     *
     * @param int $orderId 必须 int
     * @param $shopId
     * @return int
     */
    public static function verificationOrderCoupon(int $orderId, $shopId): int
    {
        // 获取订单所用的优惠券列表
        $couponList = self::query()->where('orderId', $orderId)->get();

        if ($couponList->isNotEmpty()) {
            // 更新所有订单使用了的优惠券
            self::query()->where('orderId', $orderId)->update(['status' => self::STATUS_USED]);

            $customerCouponIds = $couponList->pluck('customerCouponId')->filter();

            if ($customerCouponIds->count() > 0) {

                CustomerCouponModel::query()->whereIn('id', $customerCouponIds)
                                   ->update([
                                       'status'    => CodeEnum::COUPON_STATUS_USED,
                                       'useTime'   => time(),
                                       'useShopId' => $shopId
                                   ]);

                $customerCouponList = CustomerCouponModel::query()->whereIn('id', $customerCouponIds)->get();

                // 记录用户日志
                foreach ($customerCouponList as $item) {
                    (new CustomerActionLogService())
                        ->setUnionIdByUserId($item->userId)
                        ->asynSaveData([
                            'userId'   => $item->userId,
                            'type'     => CustomerActionLogModel::ACTION_TYPE_USE_ACTIVITY_COUPON,
                            'userInfo' => [
                                'shopId'     => $shopId,
                                'couponCode' => $item->couponCode ?? '',
                                'couponId'   => $item->couponId ?? '',
                                'activityId' => $item->activityId ?? ''
                            ]
                        ]);
                }

                // 清除核销券缓存
                foreach ($customerCouponIds as $customerCouponId) {
                    Cache::forget(CustomerCouponCacheEnum::getUserCouponStatusKey($customerCouponId));
                }
            }
        }
        return true;
    }

    /**
     * 根据 coupon source 来获取优惠券信息
     *
     * @param int $orderId
     * @param int $source
     */
    public static function getOrderCouponListByCouponSource(
        int $orderId,
        $source = OrderCouponSplitModel::COUPON_SOURCE_COUPON_PACKAGE
    ) {
        // 获取订单所用的优惠券列表
        $couponList = self::query()
                          ->where('orderId', $orderId)
                          ->where('couponSource', $source)
                          ->where('status', self::STATUS_USED)
                          ->get();

        return $couponList;

    }

    /**
     * 撤销 订单 使用的所有优惠券
     * @param $orderId
     * @return int
     */
    public static function cancelOrderCoupon($orderId): int
    {
        // 获取订单所用的优惠券列表
        $couponList = self::query()->where('orderId', $orderId)->get();

        if ($couponList->isNotEmpty()) {
            // 更新所有订单使用了的优惠券
            self::query()->where('orderId', $orderId)->update(['isDeleted' => 1]);

            $customerCouponIds = $couponList->pluck('customerCouponId')->filter();

            CustomerCouponModel::query()->whereIn('id', $customerCouponIds)
                               ->update(['status' => CodeEnum::COUPON_STATUS_NO_USED]);

            // 清除核销券缓存
            foreach ($customerCouponIds as $customerCouponId) {
                Cache::forget(CustomerCouponCacheEnum::getUserCouponStatusKey($customerCouponId));
            }

        }
        return true;
    }

    /**
     * 撤销 使用的优惠券信息
     *
     * @param array $customCouponRowId
     * @return bool
     */
    public static function cancelOrderCouponById(array $customCouponRowId = [])
    {
        /**
         * 以防撤回错误, 必须传 orderId
         */
        $customCouponRowId = array_filter($customCouponRowId);
        if (empty($customCouponRowId)) {
            return false;
        }

        // 如果有使用人信息 撤回用户的券信息
        self::cancelUserCouponById($customCouponRowId);

        return true;
    }

    /**
     * 撤回用户的券信息
     *
     * @param $ids
     * @return int
     */
    public static function cancelUserCouponById($ids)
    {
        $data = CustomerCouponModel::query()
                                   ->whereIn('id', $ids)
                                   ->update([
                                       'status'    => CodeEnum::COUPON_STATUS_NO_USED,
                                       'useTime'   => 0,
                                       'useShopId' => 0
                                   ]);

        // 清除核销券缓存
        foreach ($ids as $customerCouponId) {
            Cache::forget(CustomerCouponCacheEnum::getUserCouponStatusKey($customerCouponId));
        }

        Log::channel('order')->debug('order_coupon_model_cancelUserCouponById', [
            'msg' => '用户优惠券被撤销了',
            'id'  => $ids,
        ]);
        return $data;
    }

}
